﻿using System;
using System.Configuration;
using System.Threading;
using System.Threading.Tasks;
using GurLoader.Preferences;
using GurLoader.Service;
using GurLoader.Service.ImgurTaskBuilder;
using GurLoader.Service.Mailslot;
using GurLoader.Service.MessageProcessing;

namespace GurLoader
{
    public class ListenerLoop
    {
        public delegate void CommandPreparedEventHanlder(object sender, CommandPreparedEventArgs args);
        
        public ListenerLoop(GurLoaderPreferences appPreferences, MessageProcessingService messageService, IAppConfiguration config)
        {
            if (appPreferences == null)
                throw new ArgumentNullException("appPreferences");

            if (messageService == null)
                throw new ArgumentNullException("messageService");

            if (config == null)
                throw new ArgumentNullException("config");

            AppPreferences = appPreferences;
            MessageService = messageService;
            AppConfiguration = config;
        }

        private Preferences.GurLoaderPreferences AppPreferences { get; set; }
        private MessageProcessingService MessageService { get; set; }
        private IAppConfiguration AppConfiguration { get; set; }

        public event CommandPreparedEventHanlder CommandPrepared;
        public event EventHandler<EventArgs> ListenerStarted;

        public void Start()
        {
            Task.Factory.StartNew(ProcessCommands);
        }

        private void ProcessCommands()
        {
            string mailboxName = AppConfiguration.Settings["mailboxName"];
            var mailslotListener = new MailslotService(mailboxName);
            mailslotListener.CommandReceived += (sender, args) =>
            {
                var progress = new Progress<IDelegatingCommandProgress>();
                var ctSource = new CancellationTokenSource();

                Task<ImgurProcessResult> task = MessageService.ProcessMessage<ImgurProcessResult>(
                    args.Command, progress, ctSource.Token);

                if (CommandPrepared != null)
                    CommandPrepared(this, new CommandPreparedEventArgs(task, ctSource, progress));
            };
            mailslotListener.Start();
            if (ListenerStarted != null)
                ListenerStarted(this, EventArgs.Empty);
        }
    }
}